use std::{
    collections::HashMap,
    sync::{Arc, Mutex},
};

use anyhow::Ok;
use model_graph_types::{
    container::workflow::{
        WorkflowBlock, WorkflowBlockBody, WorkflowBlockBuilder, WorkflowBlockExecuteResult,
        WorkflowBlockExecuteResultBuilder, WorkflowBlockExecuteResultStatus, WorkflowBlockReturn,
        WorkflowBlockReturnVariable, WorkflowGraphNodeEnd,
    },
    modeling::Value,
};

use crate::workflow::context::{Getter, WorkflowContext};

pub async fn compile(id: &String, node: &WorkflowGraphNodeEnd) -> anyhow::Result<WorkflowBlock> {
    return Ok(WorkflowBlockBuilder::default()
        .id(id)
        .body(WorkflowBlockBody::Return(WorkflowBlockReturn {
            exports: node
                .outputs
                .iter()
                .map(|i| WorkflowBlockReturnVariable {
                    variable: i.variable.clone(),
                    value_selector: i.value_selector.clone(),
                })
                .collect(),
        }))
        .build()?);
}

pub fn execute(
    block: &WorkflowBlockReturn,
    context: Arc<Mutex<WorkflowContext>>,
) -> anyhow::Result<WorkflowBlockExecuteResult> {
    //
    let mut outputs: HashMap<String, Value> = HashMap::new();

    for item in &block.exports {
        //从context中获取值
        let value = context.get_from_node(&item.value_selector.1, &item.value_selector.0)?;
        outputs.insert(item.variable.clone(), value);
    }

    Ok(WorkflowBlockExecuteResultBuilder::default()
        .status(WorkflowBlockExecuteResultStatus::Succeeded)
        .is_return(true)
        .result(outputs)
        .build()?)
}
